package com.chao.demo.controller;

import com.chao.demo.bean.User;
import com.chao.demo.server.TestServer;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

@Api(value = "测试API", tags = {"测试API"})
@RestController
@RequestMapping("/api")
public class TestController {

    @Autowired
    private TestServer testServer;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @ApiOperation(value = "测试请求", notes = "测试请求")
    @GetMapping("/hello")
    public String TestRequest() {
        List<User> users = testServer.selectUserAll();
        return users.get(0).getAccount() + "访问成功";
    }

    @ApiOperation(value = "脱敏请求", notes = "脱敏请求")
    @GetMapping("/all")
    public List<User> getAllUser() {
        List<User> users = testServer.selectUserAll();
        return users;
    }

    @ApiOperation(value = "测试事务", notes = "测试事务")
    @PostMapping("/transactional")
    @Transactional(rollbackFor = {Exception.class, RuntimeException.class})
    public String transactionalRollback() throws InterruptedException {
        User user = testServer.updateUserStart(1);
        System.out.println(user.toString());
        // 调用B方法
        test();
        // System.out.println(2/0);
        return user.getAccount() + "的状态为：" + user.getStatus();
    }

    public void test() {
        boolean b = testServer.updateAccount();
        if (b) {
            System.out.println(b);
        }
        // System.out.println(2/0);
    }

    @ApiOperation(value = "获取sign", notes = "获取sign")
    @GetMapping("/sign")
    public String sign() {
        //1. 获取登录用户
        int userId = 5;
        //2. 获取日期
        LocalDateTime now = LocalDateTime.now();
        //3. 拼接key
        String keySuffix = now.format(DateTimeFormatter.ofPattern(":yyyyMM"));
        String key = "sign" + userId + keySuffix;// sign5:202401
        //4. 获取今天是本月的第几天
        int dayOfMonth = now.getDayOfMonth();//12-1=11
        //5. 写入redis setbit key offset 1   如果已签到则不改变
        stringRedisTemplate.opsForValue().setBit(key, dayOfMonth, true);
        return "true";
    }

    @ApiOperation(value = "获取用户本月签到记录", notes = "获取用户本月签到记录")
    @GetMapping("/getUserMonthSign")
    public int getUserMonthSign() {
        return testServer.getUserMonthSign();
    }

    @ApiOperation(value = "多线程查询用户的数量", notes = "多线程查询用户的数量")
    @GetMapping("/getAsynUserAll")
    public String getAsynUserAll() {
        long start = System.currentTimeMillis();
        ThreadPoolExecutor threadPool = new ThreadPoolExecutor(10, 20,
                0, TimeUnit.SECONDS, new LinkedBlockingDeque<>(1024));
        for (int i = 0; i < 10; i++) {
            int finalI = i;
            threadPool.execute(()->{
                List<User> users = testServer.selectUserAll();
                System.out.println(finalI +"用户总数量 = " + users.size());
            });
        }
        threadPool.shutdown();
        long end = System.currentTimeMillis();
        return "成功时间：" + (end - start) + "ms";
    }

    @ApiOperation(value = "查询用户的数量", notes = "查询用户的数量")
    @GetMapping("/getUserAll")
    public String getUserAll() {
        long start = System.currentTimeMillis();
        for (int i = 0; i < 10; i++) {
            List<User> users = testServer.selectUserAll();
            System.out.println(i +"用户总数量 = " + users.size());
        }
        long end = System.currentTimeMillis();
        return "成功时间：" + (end - start) + "ms";
    }

    @ApiOperation(value = "添加用户", notes = "添加用户")
    @GetMapping("/addUser")
    public String addUser() {
        long start = System.currentTimeMillis();
        User user = new User();
        for (int i = 0; i < 1000; i++) {
            user.setAccount("test"+i);
            user.setPassword("$10$S5GOwHjsZCb3CnZZqDRLJOTyFRGK8w9xEFGpt2kE2hIWQUU9XSeBa");
            user.setPhone("15730774682");
            testServer.addUser(user);
        }
        long end = System.currentTimeMillis();
        return "成功时间：" + (end - start) + "ms";
    }

    @ApiOperation(value = "多线程添加用户", notes = "添加用户")
    @GetMapping("/addAsynUser")
    public String addAsynUser() {
        long start = System.currentTimeMillis();
        User user = new User();
        ThreadPoolExecutor threadPool = new ThreadPoolExecutor(10, 20,
                0, TimeUnit.SECONDS, new LinkedBlockingDeque<>(1024));
        for (int i = 0; i < 1000; i++) {
            int finalI = i;
            threadPool.execute(()->{
                user.setAccount("test"+ finalI);
                user.setPassword("$10$S5GOwHjsZCb3CnZZqDRLJOTyFRGK8w9xEFGpt2kE2hIWQUU9XSeBa");
                user.setPhone("15730774682");
                testServer.addUser(user);
            });
        }
        threadPool.shutdown();
        long end = System.currentTimeMillis();
        return "成功时间：" + (end - start) + "ms";
    }
}
